package com.foo.designpattern.iterator;

import junit.framework.TestCase;

import java.util.ArrayList;
import java.util.List;

/**
 * com.foo.designpattern.iterator
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-05-31 13:48.
 *
 * @Description 测试类：迭代器模式(Iterator)
 * 迭代器模式：迭代器模式是行为类模式，迭代器模式提供一种方法访问一个容器对象中的各个元素，而又不暴漏该对象的内部细节。
 * 迭代器模式就是顺序访问聚集中的对象。一般来说，集合中非常常见。
 * 多个对象聚在一起形成的总体称之为聚集(Aggregate)，聚集对象是能够包容一组对象的容器对象。
 * 聚集依赖于聚集结构的抽象化，具有复杂化和多样性。数组就是最基本的聚集，也是其他的Java聚集对象的设计基础。
 * JAVA聚集对象是实现了共同的java.util.Collection接口的对象，是JAVA语言对聚集概念的直接支持。
 * 从1.2版开始，JAVA语言提供了很多种聚集，包括Vector、ArrayList、HashSet、HashMap、HashTable等，这些都是JAVA聚集的例子。
 * <p/>
 * 迭代器模式涉及到以下几个角色：
 * 1、抽象迭代器(Iterator)角色：此抽象角色定义出遍历元素所需的接口；
 * 2、具体迭代器(ConcreteIterator)角色：此角色实现了Iterator接口，并保持迭代过程中的游标位置；
 * 3、聚集(Aggregate)角色：此抽象角色给出创建迭代器(Iterator)对象的接口。
 * 4、具体聚集(ConcreteAggregate)角色：实现了创建迭代器(Iterator)对象的接口，返回一个合适的具体迭代器实例；
 * 5、客户端(Client)角色：持有对聚集及其迭代器对象的引用，调用迭代器对象的迭代接口，也有可能通过迭代器操作聚集元素的增加或删除。
 * <p/>
 * 迭代器模式的优点：
 * 1、迭代器模式简化了聚集的接口，迭代器具备了一个遍历接口，这样聚集的接口就不必具备遍历接口；
 * 2、每一个聚集对象都可以有一个或多个迭代器对象，每一个迭代器的迭代状态可以是彼此独立的。因此，一个聚集对象可以同时有几个迭代在进行之中；
 * 3、由于遍历算法被封装在迭代器角色里面，因此迭代的算法可以独立于聚集角色而变化。
 * 迭代器模式的缺点：
 * 1、对于比较简单的遍历(像数组或者有序列表)，使用迭代器方式遍历较为繁琐，比如ArrayList，一般使用for循环和get方法来遍历集合。
 * <p/>
 * 迭代器模式的真正作用是将数据结构和操作数据结构的算法分离开。
 * 在迭代器模式之前，数据结构和操作数据结构的算法是分离不开的，一定的数据结构必然有对应的算法，
 * 就算是相同的算法，如果数据结构不一样，也不能通用。自从有了迭代器模式，数据结构很算法算是彻底分离开，两者可以独立的发展。
 */

public class IteratorTestCase extends TestCase {
    public void testIterator() {
        System.out.println("= = = = ↓↓↓迭代器模式，测试开始↓↓↓ = = = =");
        // 聚集对象(2016互联网大会会议室)
        ConcreteAggregate aggregate = new ConcreteAggregate();

        // 对象集合(新到来的会议嘉宾)
        List<Object> items = new ArrayList<Object>();
        items.add("杨元庆");
        items.add("刘强东");
        items.add("王小川");
        items.add("李开复");
        items.add("雷军");
        aggregate.setItems(items);

        System.out.println("= = = = ↓↓↓正向遍历↓↓↓ = = = =");
        // 迭代器对象
        Iterator it = new ConcreteIterator(aggregate);
        // 迭代器第一个对象(从第一个嘉宾开始)
        Object item = it.first();
        while (it.hasNext()) {
            System.out.println(it.currentItem() + "请出示参会邀请函");
            it.next();
        }

        System.out.println("= = = = ↓↓↓反向遍历↓↓↓ = = = =");
        // 迭代器对象
        Iterator itDesc = new ConcreteIteratorDesc(aggregate);
        // 迭代器第一个对象(从第一个嘉宾开始)
        Object itemDesc = itDesc.first();
        while (itDesc.hasNext()) {
            System.out.println(itDesc.currentItem() + "请出示参会邀请函");
            itDesc.next();
        }

        System.out.println("= = = = ↑↑↑迭代器模式，测试结束↑↑↑ = = = =");
    }
}
